/* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
//
// Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
// All rights reserved.
//
// This file is part of SDLPAL.
//
// SDLPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef BATTLE_H
#define BATTLE_H

#ifdef __cplusplus
extern "C" {
#endif

#include "global.h"
#include "uibattle.h"

#define BATTLE_FPS 25
#define BATTLE_FRAME_TIME (1000 / BATTLE_FPS)

typedef enum tagBATTLERESULT {
   kBattleResultWon = 3,          // player won the battle
   kBattleResultLost = 1,         // player lost the battle
   kBattleResultFleed = 0xFFFF,   // player fleed from the battle
   kBattleResultTerminated = 0,   // battle terminated with scripts
   kBattleResultOnGoing = 1000,   // the battle is ongoing
   kBattleResultPreBattle = 1001, // running pre-battle scripts
   kBattleResultPause = 1002,     // battle pause
} BATTLERESULT;

typedef enum tagFIGHTERSTATE {
   kFighterWait, // waiting time
   kFighterCom,  // accepting command
   kFighterAct,  // doing the actual move
} FIGHTERSTATE;

typedef enum tagBATTLEACTIONTYPE {
   kBattleActionPass,       // do nothing
   kBattleActionDefend,     // defend
   kBattleActionAttack,     // physical attack
   kBattleActionMagic,      // use magic
   kBattleActionCoopMagic,  // use cooperative magic
   kBattleActionFlee,       // flee from the battle
   kBattleActionThrowItem,  // throw item onto enemy
   kBattleActionUseItem,    // use item
   kBattleActionAttackMate, // attack teammate (confused only)
} BATTLEACTIONTYPE;

typedef struct tagBATTLEACTION
{
   BATTLEACTIONTYPE ActionType;
   WORD wActionID;        // item/magic to use
   SHORT sTarget;         // -1 for everyone
   float flRemainingTime; // remaining waiting time before the action start
} BATTLEACTION;

typedef struct tagBATTLEENEMY
{
   WORD wObjectID;                      // Object ID of this enemy
   ENEMY e;                             // detailed data of this enemy
   WORD rgwStatus[kStatusAll];          // status effects
   float flTimeMeter;                   // time-charging meter (0 = empty, 100 = full).
   POISONSTATUS rgPoisons[MAX_POISONS]; // poisons
   LPSPRITE lpSprite;
   PAL_POS pos;         // current position on the screen
   PAL_POS posOriginal; // original position on the screen
   WORD wCurrentFrame;  // current frame number
   FIGHTERSTATE state;  // state of this enemy

   BOOL fTurnStart;
   BOOL fFirstMoveDone;
   BOOL fDualMove;

   WORD wScriptOnTurnStart;
   WORD wScriptOnBattleEnd;
   WORD wScriptOnReady;

   WORD wPrevHP; // HP value prior to action

   INT iColorShift;
} BATTLEENEMY;

// We only put some data used in battle here; other data can be accessed in the global data.
typedef struct tagBATTLEPLAYER
{
   INT iColorShift;
   float flTimeMeter; // time-charging meter (0 = empty, 100 = full).
   float flTimeSpeedModifier;
   WORD wHidingTime; // remaining hiding time
   LPSPRITE lpSprite;
   PAL_POS pos;         // current position on the screen
   PAL_POS posOriginal; // original position on the screen
   WORD wCurrentFrame;  // current frame number
   FIGHTERSTATE state;  // state of this player
   BATTLEACTION action; // action to perform
   BOOL fDefending;     // TRUE if player is defending
   WORD wPrevHP;        // HP value prior to action
   WORD wPrevMP;        // MP value prior to action
#ifndef PAL_CLASSIC
   SHORT sTurnOrder; // turn order
#endif
} BATTLEPLAYER;

typedef struct tagSUMMON
{
   LPSPRITE lpSprite;
   WORD wCurrentFrame;
} SUMMON;

#define MAX_BATTLE_ACTIONS 256
#define MAX_KILLED_ENEMIES 256

#ifdef PAL_CLASSIC

typedef enum tabBATTLEPHASE {
   kBattlePhaseSelectAction,
   kBattlePhasePerformAction
} BATTLEPHASE;

typedef struct tagACTIONQUEUE
{
   BOOL fIsEnemy;
   WORD wDexterity;
   WORD wIndex;
} ACTIONQUEUE;

#define MAX_ACTIONQUEUE_ITEMS (MAX_PLAYERS_IN_PARTY + MAX_ENEMIES_IN_TEAM * 2)

#endif

typedef struct tagBATTLE
{
   BATTLEPLAYER rgPlayer[MAX_PLAYERS_IN_PARTY];
   BATTLEENEMY rgEnemy[MAX_ENEMIES_IN_TEAM];

   WORD wMaxEnemyIndex;

   SDL_Surface *lpSceneBuf;
   SDL_Surface *lpBackground;

   SHORT sBackgroundColorShift;

   LPSPRITE lpSummonSprite; // sprite of summoned god
   PAL_POS posSummon;
   INT iSummonFrame; // current frame of the summoned god

   INT iExpGained;  // total experience value gained
   INT iCashGained; // total cash gained

   BOOL fIsBoss;       // TRUE if boss fight
   BOOL fEnemyCleared; // TRUE if enemies are cleared
   BATTLERESULT BattleResult;

   float flTimeChargingUnit; // the base waiting time unit

   BATTLEUI UI;

   LPBYTE lpEffectSprite;

   BOOL fEnemyMoving; // TRUE if enemy is moving

   INT iHidingTime; // Time of hiding

   WORD wMovingPlayerIndex; // current moving player index

   int iBlow;

#ifdef PAL_CLASSIC
   BATTLEPHASE Phase;
   ACTIONQUEUE ActionQueue[MAX_ACTIONQUEUE_ITEMS];
   int iCurAction;
   BOOL fRepeat; // TRUE if player pressed Repeat
   BOOL fForce;  // TRUE if player pressed Force
   BOOL fFlee;   // TRUE if player pressed Flee
#endif
} BATTLE;

extern BATTLE g_Battle;

VOID
    PAL_LoadBattleSprites(
        VOID);

VOID
    PAL_BattleMakeScene(
        VOID);

VOID
    PAL_BattleBackupScene(
        VOID);

VOID
    PAL_BattleFadeScene(
        VOID);

VOID
    PAL_BattleEnemyEscape(
        VOID);

VOID
    PAL_BattlePlayerEscape(
        VOID);

BATTLERESULT
PAL_StartBattle(
    WORD wEnemyTeam,
    BOOL fIsBoss);

#ifdef __cplusplus
}
#endif

#endif
